import { ref, watch, type Ref } from "vue"

type DoPageRequestFunc<T> = (pageNo: number, pageSize: number) => Promise<PageRequestResult<T> | undefined>
interface PageRequestResult<T> { datas: Array<T>, total: number }
interface PageRequestError { code: number, message: string }

export default function usePageRequest<T>(doRequestFunc: DoPageRequestFunc<T>, watchSource: Ref<any>[] = [], initPageNo: number = 1, initPageSize: number = 10) {
    const list = ref<Array<T>>([]) as Ref<Array<T>>
    const pageNo = ref(initPageNo)
    const pageSize = ref(initPageSize)
    const total = ref(0)
    const loading = ref(false)
    const error = ref<PageRequestError | null>(null)


    const doRequest = async () => {
        loading.value = true
        error.value = null;
        try {
            const result = (await doRequestFunc(pageNo.value, pageSize.value)) as PageRequestResult<T>
            list.value = result.datas
            total.value = result.total
        } catch (e) {
            error.value = e as PageRequestError
        } finally {
            loading.value = false
        }
    }
    
    watch([pageNo, pageSize, ...watchSource], doRequest)

    return { doRequest, list, pageNo, pageSize, total, loading, error }
}